using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;

namespace PiratesOfBermuda
{
    public class Cannon : DrawableGameComponent
    {
        #region Fields & Accessors
        protected string _identifier;

        public string Identifier
        {
            get { return _identifier; }
            set { _identifier = value; }
        }

        //Khoang cach toi da ma 1 qua cannon co the ban duoc
        public const int AttackRange = 3;
        //Luu thong tin can thiet
        Ship myBoss;
        MyPiratesGame currentGame;
        SpriteBatch spriteBatch;

        //Textures
        Texture2D Texture;
        Texture2D explodeTexture;
        Texture2D splashTexture;

        internal Animation lowerExplodeAnimation;
        internal Animation upperExplodeAnimation;

        Point p1;

        public Point P1
        {
            get { return p1; }
        }
        Point p2;

        public Point P2
        {
            get { return p2; }
        }

        bool is1Exploded;

        public bool Is1Exploded
        {
            get { return is1Exploded; }
        }
        bool is2Exploded;

        public bool Is2Exploded
        {
            get { return is2Exploded; }
        }

        public bool IsAnimating
        {
            get 
            {
                return (lowerExplodeAnimation != null && lowerExplodeAnimation.IsActive) 
                    || (upperExplodeAnimation != null && upperExplodeAnimation.IsActive)
                    || q1.Count != 0
                    || q2.Count != 0
                    || !IsInitialized;
            }
        }

        //Destionation Queue de ve len man hinh
        public Queue<Rectangle> q1 = new Queue<Rectangle>();
        public Queue<Rectangle> q2 = new Queue<Rectangle>();
        #endregion

        public Cannon(Game game, SpriteBatch spriteBatch, Ship boss)
            : base(game)
        {
            _identifier = "Cannon";
            myBoss = boss;
            currentGame = (MyPiratesGame)game;            
            this.spriteBatch = spriteBatch;
            IsInitialized = false;
        }

        public override void Initialize()
        {
            Texture = currentGame.Content.Load<Texture2D>(@"Textures/MainGameplay/cannon");
            explodeTexture = currentGame.Content.Load<Texture2D>(@"Textures/MainGameplay/cannonblast");
            splashTexture = currentGame.Content.Load<Texture2D>(@"Textures/MainGameplay/splash");
            base.Initialize();
        }

        void MakeMovingAnimation(Point p, Queue<Rectangle> q)
        {
            int X = myBoss.X;
            int Y = myBoss.Y;
            if (myBoss.MainSailDirection == MainSailDirections.West || myBoss.MainSailDirection == MainSailDirections.East)
            {
                if (p.X != -1)
                {
                    int totalStepPixel = (int)(Math.Abs(p.Y - Y) / 3.0f * Constants.MapPieceHeight);
                    if (p.Y < Y)
                    {
                        for (int i = 0; i < totalStepPixel; i++)
                        {
                            q.Enqueue(new Rectangle(
                                Constants.InitialPositionX + X * Constants.MapPieceWidth + Constants.CannonOffsetX,
                                Constants.InitialPositionY + Y * Constants.MapPieceHeight - i * 3 + Constants.MapPieceHeight / 2,
                                10, 10));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < totalStepPixel - 1; i++)
                        {
                            q.Enqueue(new Rectangle(
                                Constants.InitialPositionX + X * Constants.MapPieceWidth + Constants.CannonOffsetX,
                                Constants.InitialPositionY + Y * Constants.MapPieceHeight + i * 3 + Constants.MapPieceHeight / 2,
                                10, 10));
                        }
                    }
                }
            }
            else
            {
                if (p.X != -1)
                {
                    int totalStepPixel = (int)(Math.Abs(p.X - X) / 3.0f * Constants.MapPieceWidth);
                    if (p.X < X)
                    {
                        for (int i = 0; i < totalStepPixel; i++)
                        {
                            q.Enqueue(new Rectangle(
                                Constants.InitialPositionX + X * Constants.MapPieceWidth - i * 3 + Constants.MapPieceWidth / 2,
                                Constants.InitialPositionY + Y * Constants.MapPieceHeight + Constants.CannonOffsetY,
                                10, 10));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < totalStepPixel - 1; i++)
                        {
                            q.Enqueue(new Rectangle(
                                Constants.InitialPositionX + X * Constants.MapPieceWidth + i * 3 + Constants.MapPieceWidth / 2,
                                Constants.InitialPositionY + Y * Constants.MapPieceHeight + Constants.CannonOffsetY,
                                10, 10));
                        }
                    }
                }
            }
        }

        public void Fire(Point? p1, bool is1Exploded, Point? p2, bool is2Exploded)
        {
            if (p1 != null)
            {
                this.p1 = (Point)p1;
                this.is1Exploded = is1Exploded;
                MakeMovingAnimation((Point)p1, q1);
                if (is1Exploded)
                    lowerExplodeAnimation = new Animation(explodeTexture, new Point(20, 28), new Point(15, 1), (Point)p1);
                else
                    lowerExplodeAnimation = new Animation(splashTexture, new Point(40, 40), new Point(24, 1), (Point)p1);
            }
            if (p2 != null)
            {
                this.p2 = (Point)p2;
                this.is2Exploded = is2Exploded;

                MakeMovingAnimation((Point)p2, q2);
                if (is2Exploded)
                    upperExplodeAnimation = new Animation(explodeTexture, new Point(20, 28), new Point(15, 1), (Point)p2);
                else
                    upperExplodeAnimation = new Animation(splashTexture, new Point(40, 40), new Point(24, 1), (Point)p2);
            }
            IsInitialized = true;
        }

        public void MakeLowerExlode()
        {
            if (lowerExplodeAnimation != null)
            {
                lowerExplodeAnimation.PlayFromFrameIndex(0);
            }
        }

        public void MakeUpperExplode()
        {
            if (upperExplodeAnimation != null)
            {
                upperExplodeAnimation.PlayFromFrameIndex(0);
            }
        }
        public void Update()
        {
            if (lowerExplodeAnimation != null)
            {
                lowerExplodeAnimation.Update();
            }

            if (upperExplodeAnimation != null)
            {
                upperExplodeAnimation.Update();
            }   
        }

        public override void Draw(GameTime gameTime)
        {
            if (q1.Count > 0)
                spriteBatch.Draw(Texture, q1.Dequeue(), Color.White);
            else if (lowerExplodeAnimation != null && lowerExplodeAnimation.IsActive)
                lowerExplodeAnimation.Draw(spriteBatch);


            if (q2.Count > 0)
                spriteBatch.Draw(Texture, q2.Dequeue(), Color.White);
            else if (upperExplodeAnimation != null && upperExplodeAnimation.IsActive)
                upperExplodeAnimation.Draw(spriteBatch);

            base.Draw(gameTime);
        }


        public bool IsInitialized { get; set; }
    }
}
